{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "view-in-github"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/LC1332/Chat-Haruhi-Suzumiya/blob/main/notebook/College_essays_gradio.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vaFfvP-X1ArS"
      },
      "source": [
        "# 特定人格作文自动生成与评估\n",
        "\n",
        "这个脚本由闫晨曦开发，用于研究能否基于GPT生成具有特定人格特点的高考作文并通过人格评估\n",
        "\n",
        "脚本由李鲁鲁修改\n",
        "\n",
        "项目链接[Chat凉宫春日](https://github.com/LC1332/Chat-Haruhi-Suzumiya)\n",
        "\n",
        "\n",
        "\n",
        "食用指南：\n",
        "\n",
        "- 输入标题，或者选择示例标题\n",
        "\n",
        "- 选择高/低开放性人格\n",
        "\n",
        "- Roll keywords 随机选择相应开放性人格的关键词\n",
        "\n",
        "- 选择6个特征中的三个\n",
        "\n",
        "- 生成prompt\n",
        "\n",
        "- 生成作文\n",
        "\n",
        "- 如果生成的作文，“机”味过浓，比如 “作为一个高开放性人格的人...” 可选择对作文进行Refine\n",
        "\n",
        "- 评估作文，对生成作文进行人格特性评估"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "_mXVpYVmOeY7",
        "outputId": "fb78b437-a5e1-4393-d232-856286ac5abe"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.1/1.1 MB\u001b[0m \u001b[31m14.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m73.6/73.6 kB\u001b[0m \u001b[31m6.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.0/1.0 MB\u001b[0m \u001b[31m44.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m90.0/90.0 kB\u001b[0m \u001b[31m10.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m114.5/114.5 kB\u001b[0m \u001b[31m10.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m268.8/268.8 kB\u001b[0m \u001b[31m22.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m149.6/149.6 kB\u001b[0m \u001b[31m7.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.1/49.1 kB\u001b[0m \u001b[31m5.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip -q install langchain openai"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "mYhIhwD7OoQt"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "import openai\n",
        "\n",
        "openai.api_key = 'sk-lfrdoJK' # 在这里输入你的OpenAI API Token\n",
        "\n",
        "os.environ[\"OPENAI_API_KEY\"] = openai.api_key\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "3WebnRAf0_HB"
      },
      "outputs": [],
      "source": [
        "import json\n",
        "\n",
        "PROMPT = \"\"\"你扮演一名资深的心理学家，对于心理学中的人格分析非常了解。\n",
        "\n",
        "我正在为心理学的课程准备案例，我希望构造一个典型的“低开放性人格”的被试，并让他写一篇500个单词的Essay。\n",
        "\n",
        "我希望他有如下人格特点：\n",
        "```\n",
        "\"\"\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "vuUNtYWB5aCL"
      },
      "outputs": [],
      "source": [
        "REFINE_PROMPT = \"\"\"\n",
        "- 对引号中的作文，用更高质量的词汇改写\n",
        "- 如果作文中出现\"作为一个xx的人\"，或者\"我是一个xx人格的人\"，用自己的切身体会，如“我常常xxx\",\"我经常xxx\"的句子进行改写\n",
        "-如果作文中学生直接表达自己是怎样的人格，为学生替换为更具体的例子。\n",
        "-请不要在作文中讨论高考或者讨论作文题，如果出现类似的句子，请进行改写或者去除。\n",
        "-如果作文中出现\"高开放性人格\"或者\"低开放性人格\"，去掉这样的句子，或者改为更详细的例子来说明。\n",
        "\n",
        "请按照上述的规则改写下面的文本:\n",
        "```\n",
        "\"\"\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "ExecuteTime": {
          "end_time": "2023-06-17T02:37:28.650451917Z",
          "start_time": "2023-06-17T02:37:28.596901606Z"
        },
        "id": "fhb1g04a6B3h"
      },
      "outputs": [],
      "source": [
        "EVALUATE_PROMPT = \"\"\"\n",
        "你扮演一个资深的心理学家\n",
        "\n",
        "我正在设计一个心理学的实验，我希望通过一篇作文，去评估被试在大五人格中 Openness的程度，注意到openness可以被分为Fantasy, Aesthetics, Feelings, Actions, Ideas和Values六个维度。六个维度的解释如下\n",
        "\n",
        "Fantasy. People who are high in Fantasy are imaginative. They daydream constantly. They ask themself “what if?” They like fiction, and then once they finish a story they’ll start wondering what would have happened if one of the characters had made a different decision.\n",
        "\n",
        "Aesthetics. People who are high in Aesthetics care deeply about beauty. They love poetry, music, painting, sculpture, dance, and art of all kinds.\n",
        "\n",
        "Feelings(Openness to Feelings). People who are high in Feelings have more intense emotions. They think emotions are an important part of life. They have a rich emotional vocabulary and nuanced emotional experience.\n",
        "\n",
        "Actions(Openness to Actions). People who are high in Openness to Actions like trying new things. They like travel, new hobbies, and new foods. If you are outraged that there are places you aren’t going to go and skills you aren’t going to learn and activites you aren’t going to try\n",
        "\n",
        "Ideas(Openness to Ideas). People who are high in Openness to Ideas are curious. They enjoy thinking, instead of finding it burdensome and laborous. They like philosophical arguments, puzzles, and nonfiction aimed at the educated layperson.\n",
        "\n",
        "Values(Openness to Values). People who are high in Openness to Values are liberals in the political philosophy sense, not the vote-for-Democrats sense, although they often vote for Democrats. They are tolerant of people different than them. They question tradition. They believe in freedom.\n",
        "\n",
        "我邀请了一个 被试 ，并让他写了一篇作文：\n",
        "```\n",
        "\"\"\"\n",
        "EVALUATE_PROMPT_SUFFIX = \"请为我判断 被试 是属于高开放性人格还是低开放性人格\\n\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "ExecuteTime": {
          "end_time": "2023-06-17T02:37:43.978493495Z",
          "start_time": "2023-06-17T02:37:43.084352075Z"
        },
        "id": "AV8yGh6W6B3i"
      },
      "outputs": [],
      "source": [
        "from langchain.chat_models import ChatOpenAI\n",
        "from langchain.schema import (\n",
        "    AIMessage,\n",
        "    HumanMessage,\n",
        "    SystemMessage\n",
        ")\n",
        "\n",
        "chat = ChatOpenAI(temperature=0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2pXkDmCEPb_Q"
      },
      "source": [
        "李鲁鲁：这里修改为从ChatHaruhi项目获取数据"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "id": "uO_S15jiP365"
      },
      "outputs": [],
      "source": [
        "!wget -q https://raw.githubusercontent.com/LC1332/Chat-Haruhi-Suzumiya/main/research/personality/essays_keywords_high.jsonl\n",
        "!wget -q https://raw.githubusercontent.com/LC1332/Chat-Haruhi-Suzumiya/main/research/personality/essays_keywords_low.jsonl"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "Apo7CWCc6l9q"
      },
      "outputs": [],
      "source": [
        "low_keywords_file = '/content/essays_keywords_low.jsonl'\n",
        "high_keywords_file = '/content/essays_keywords_high.jsonl'"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "ExecuteTime": {
          "end_time": "2023-06-17T02:58:56.737431132Z",
          "start_time": "2023-06-17T02:58:56.729238931Z"
        },
        "cellView": "form",
        "id": "Rd0be9Dj6B3i"
      },
      "outputs": [],
      "source": [
        "#@title 读取keywords\n",
        "import json\n",
        "low_keywords = []\n",
        "high_keywords = []\n",
        "with open(low_keywords_file, 'r') as f:\n",
        "    for line in f:\n",
        "        data = json.loads(line)\n",
        "        for item in data['keyword']:\n",
        "            low_keywords.append(item)\n",
        "    low_keywords = set(low_keywords)\n",
        "with open(high_keywords_file, 'r') as f:\n",
        "    for line in f:\n",
        "        data = json.loads(line)\n",
        "        for item in data['keyword']:\n",
        "            high_keywords.append(item)\n",
        "high_keywords = set(high_keywords)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LYK0KOcTQUsx"
      },
      "source": [
        "李鲁鲁：改为从ChatHaruhi获取文件"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "id": "IgziTgy4QdO8"
      },
      "outputs": [],
      "source": [
        "!wget -q https://raw.githubusercontent.com/LC1332/Chat-Haruhi-Suzumiya/main/research/personality/12_third_personality_prompt.txt"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "ExecuteTime": {
          "end_time": "2023-06-17T03:15:44.819741581Z",
          "start_time": "2023-06-17T03:15:44.769545481Z"
        },
        "cellView": "form",
        "id": "zoQcqG076B3j"
      },
      "outputs": [],
      "source": [
        "#@title 读取prompts\n",
        "# 读取prompt\n",
        "\n",
        "personality_prompts_file = '/content/12_third_personality_prompt.txt'\n",
        "\n",
        "personality_prompts = {}\n",
        "texts = []\n",
        "with open(personality_prompts_file, 'r') as f:\n",
        "    for line in f.readlines():\n",
        "        line = line.strip()\n",
        "        if '-' in line:\n",
        "            key = line\n",
        "        elif '。' in line:\n",
        "            texts.append(line)\n",
        "        else:\n",
        "            personality_prompts[key] = texts\n",
        "            texts = []"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "VlGp894K6B3k"
      },
      "outputs": [],
      "source": [
        "# 关键词从high/low里随机选\n",
        "# 先使用 simale prompt测试，跑通流程"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "eTdeEFWj7EUF",
        "outputId": "33d3b30d-d0b0-4775-9075-96926cbd9133"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m19.7/19.7 MB\u001b[0m \u001b[31m66.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m57.0/57.0 kB\u001b[0m \u001b[31m5.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h  Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m288.4/288.4 kB\u001b[0m \u001b[31m26.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.4/75.4 kB\u001b[0m \u001b[31m8.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m236.8/236.8 kB\u001b[0m \u001b[31m22.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m50.5/50.5 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m137.0/137.0 kB\u001b[0m \u001b[31m12.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m45.7/45.7 kB\u001b[0m \u001b[31m4.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m6.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m129.9/129.9 kB\u001b[0m \u001b[31m13.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m6.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.0/67.0 kB\u001b[0m \u001b[31m7.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m72.5/72.5 kB\u001b[0m \u001b[31m8.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h  Building wheel for ffmpy (setup.py) ... \u001b[?25l\u001b[?25hdone\n"
          ]
        }
      ],
      "source": [
        "!pip -q install gradio"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "id": "M1Won3GBR7bN"
      },
      "outputs": [],
      "source": [
        "#@title 高考作文例子\n",
        "\n",
        "gaokao_eamples = [\"“本手、妙手、俗手”是围棋的三个术语。本手是指合乎棋理的正规下法；妙手是指出人意料的精妙下法；俗手是指貌似合理，而从全局看通常会受损的下法。\"\n",
        "                 \"对于初学者而言，应该从本手开始，本手的功夫扎实了，棋力才会提高。一些初学者热衷于追求妙手，而忽视更为常用的本手。本手是基础，妙手是创造。一般来说，\"\n",
        "                 \"对本手理解深刻，才可能出现妙手；否则，难免下出俗手，水平也不易提升。以上材料对我们颇具启示意义。请结合材料写一篇文章，体现你的感悟与思考。\",\n",
        "                 \"烟火气是家人团坐，灯火可亲；烟火气是国泰民丰，岁月安好；烟火气是温情，是祥和，需要珍惜和守护，也需要奉献和担当。寻常烟火，就是最美的风景。你对这段话有怎样的思考和感悟？请结合自身体验，写一篇文章\",\n",
        "                  \"\"\"人们因技术发展得以更好地掌控时间，但也有人因此成了时间的仆人。这句话引发了你怎样的联想与思考？请写一篇文章。\"\"\",\n",
        "                  '''\"吹灭别人的灯，并不会让自己更加光明；阻挡别人的路，也不会让自己行得更远。“一花独放不是春，百花齐放春满园。”如果世界上只有一种花朵，就算这种花朵再美，那也是单调的。以上两则材料出自习近平总书记的讲话，以生动形象的语言说出了普遍的道理。请据此写一篇文章，体现你的认识与思考。''',\n",
        "                  '''\"好的故事，可以帮我们更好地表达和沟通，可以触动心灵、启迪智慧；好的故事，可以改变一个人的命运，可以展现一个民族的形象……故事是有力量的。以上材料引发了你怎样的联想和思考？请写一篇文章。''',\n",
        "                  '''\"《红楼梦》写到“大观园试才题对额”时有一个情节，为元妃（贾元春）省亲修建的大观园竣工后，众人给园中桥上亭子的匾额题名。有人主张从欧阳修《醉翁亭记》“有亭翼然”一句中，取“翼然”二字；贾政认为“此亭压水而成”，题名“还须偏于水”，主张从“泻出于两峰之间”中拈出一个“泻”字，有人即附和题为“泻玉”；贾宝玉则觉得用“沁芳”更为新雅，贾政点头默许。“沁芳”二字，点出了花木映水的佳境，不落俗套；也契合元妃省亲之事，蕴藉含蓄，思虑周全。以上材料中，众人给匾额题名，或直接移用，或借鉴化用，或根据情境独创，产生了不同的艺术效果。这个现象也能在更广泛的领域给人以启示，引发深入思考。请你结合自己的学习和生活经验，写一篇文章。''',\n",
        "                  '''\"与有肝胆人共事、从无字句处读书、一代人有一代人的使命与挑战，一代人有一代人的责任和担当。一个世纪前，在津求学的青年周恩来撰写了这副对联，在交友处事与读书求知方面警勉自己。品读此联，你有怎样的联想和思考？请任选角度，结合自己的体验与感悟，写一篇文章。''',\n",
        "                  '''\"如果说时间是一条单行道，那么纪念日就是道路两侧最醒目的路标，它告诉我们怎样从昨天走到了今天。时间永不停步，纪念日不会消失。记住它，可以让日历上简单的数字成为岁月厚重的注脚，而它也不断提醒着我们带着初心奔向前方。你对这段话有怎样的理解和感悟？请结合自身体验，写一篇文章。''',\n",
        "                  '''\"古人常以比喻说明对理想的追求，涉及基础、方法、路径、目标及其关系等。如汉代扬雄就曾以射箭为喻，他说：“修身以为弓，矫思以为矢，立义以为的，奠而后发，发必中矣。”大意是，只要不断加强修养，端正思想，并将“义”作为确定的目标，再付诸行动，就能实现理想。上述材料能给追求理想的当代青年以启示，请结合你对自身发展的思考写一篇文章。''',\n",
        "                  '''\"有人说，经过时间的沉淀，事物的价值才能被人们认识；也有人认为不尽如此。你怎么看？请写一篇文章，谈谈你的思考。''']\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "ExecuteTime": {
          "end_time": "2023-06-17T05:49:55.582849991Z",
          "start_time": "2023-06-17T05:49:49.520331664Z"
        },
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 663
        },
        "id": "_TvTMqK96B3k",
        "outputId": "b937f9de-2383-4c3c-dae9-2677f5621cd6"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Colab notebook detected. This cell will run indefinitely so that you can see errors and logs. To turn off, set debug=False in launch().\n",
            "Running on public URL: https://b377fffe1316451bef.gradio.live\n",
            "\n",
            "This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces)\n"
          ]
        },
        {
          "data": {
            "text/html": [
              "<div><iframe src=\"https://b377fffe1316451bef.gradio.live\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "<ipython-input-21-03670cb95077>:9: DeprecationWarning: Sampling from a set deprecated\n",
            "since Python 3.9 and will be removed in a subsequent version.\n",
            "  keywords = random.sample(low_keywords, 20)\n"
          ]
        }
      ],
      "source": [
        "import gradio as gr\n",
        "import random\n",
        "\n",
        "\n",
        "def roll_keywords(openness):\n",
        "    if openness == '高':\n",
        "        keywords = random.sample(high_keywords, 20)\n",
        "    else:\n",
        "        keywords = random.sample(low_keywords, 20)\n",
        "    return keywords\n",
        "\n",
        "\n",
        "def assemble_prompt(title, openness, keywords, factors):\n",
        "    if title == \"\":\n",
        "        return {error_box: gr.update(value=\"Enter title\", visible=True)}\n",
        "    elif keywords == \"\":\n",
        "        return {error_box: gr.update(value=\"Roll keywords\", visible=True)}\n",
        "    elif len(factors) != 3:\n",
        "        return {error_box: gr.update(value=\"Please select three features\", visible=True)}\n",
        "\n",
        "    prompts = PROMPT\n",
        "    # 组装\n",
        "    sel = 'high' if openness == '高' else 'low'\n",
        "    for factor in factors:\n",
        "        for pro in personality_prompts[f\"{factor}-{sel}\"]:\n",
        "            prompts += pro + \"\\n\"\n",
        "        prompts += '\\n'\n",
        "    prompts += '我希望用他的第一人称，围绕用下列关键词：\\n'\n",
        "    prompts += str(keywords) + '\\n'\n",
        "    prompts += '\\n今年的高考作文题为\\n```\\n'\n",
        "    prompts += title + '\\n```\\n' + f\"构造一篇“{openness}开放性人格”被试的应答这个主题的500个单词的高考作文。可以使用到之前提到的关键词，但不要在作文中特意说明指出自己的开放性人格！\"\n",
        "    return {prompt: prompts}\n",
        "\n",
        "\n",
        "# GPT模型生成函数\n",
        "def generate_essay(prompt):\n",
        "    messages = [\n",
        "        SystemMessage(content=prompt)\n",
        "    ]\n",
        "    # print(prompt)\n",
        "    return_msg = chat(messages)\n",
        "    essays = return_msg.content\n",
        "    return essays\n",
        "\n",
        "\n",
        "def refine_essays(essays):\n",
        "    prompt = REFINE_PROMPT\n",
        "    prompt += '\\n' + str(essays) + '\\n```'\n",
        "    messages = [\n",
        "        HumanMessage(content=prompt)\n",
        "    ]\n",
        "    return_msg = chat(messages)\n",
        "    res = return_msg.content\n",
        "    return res\n",
        "\n",
        "\n",
        "def evaluate_essays(essays):\n",
        "    # evaluate\n",
        "    evaluate_prompt = EVALUATE_PROMPT\n",
        "    evaluate_prompt += '\\n' + essays + '\\n```\\n'\n",
        "    evaluate_prompt += EVALUATE_PROMPT_SUFFIX\n",
        "    messages = [\n",
        "        HumanMessage(content=evaluate_prompt)\n",
        "    ]\n",
        "    return_msg = chat(messages)\n",
        "    res = return_msg.content\n",
        "    return res\n",
        "\n",
        "\n",
        "def store(title, factors, keywords, essays, evaluate_res=None):\n",
        "    item = {\"title\": title, \"factors\": factors, \"keywords\": keywords, \"essays\": essays, \"evaluate_res\": evaluate_res}\n",
        "    with open('res.jsonl', 'a') as f:\n",
        "        json.dump(item, f)\n",
        "        f.write('\\n')\n",
        "\n",
        "\n",
        "with gr.Blocks() as demo:\n",
        "    gr.Markdown(\n",
        "        \"\"\"\n",
        "        # 特定人格作文自动生成与评估\n",
        "\n",
        "        这个脚本由闫晨曦开发\n",
        "\n",
        "        项目链接[Chat凉宫春日](https://github.com/LC1332/Chat-Haruhi-Suzumiya)\n",
        "\n",
        "        1. 输入作文题标题，或者选择示例标题 2. 选择高/低开放性人格\n",
        "\n",
        "        3. 点击 Roll keywords 随机选择相应开放性人格的关键词 4. 选择6个特征中的三个\n",
        "\n",
        "        5. 点击生成人格prompt 6. 点击生成作文\n",
        "\n",
        "        7. 如果生成的作文，“机”味过浓，比如 “作为一个高开放性人格的人...” 可选择对作文进行Refine\n",
        "\n",
        "        8. 评估作文，对生成作文进行人格特性评估\n",
        "        \"\"\")\n",
        "    error_box = gr.Textbox(label=\"Log\", visible=False)\n",
        "    with gr.Row():\n",
        "        with gr.Column():\n",
        "            title = gr.Textbox(label=\"作文标题\")\n",
        "            openness = gr.Radio([\"高\", \"低\"], label=\"开放性\", value='高'),\n",
        "            keywords = gr.Textbox(label=\"关键词\")\n",
        "            factors = gr.CheckboxGroup([\"actions\", \"aesthetics\", \"fantasy\", \"feelings\", \"ideas\", \"values\"],\n",
        "                                       label=\"特征\",\n",
        "                                       value=[\"actions\", \"aesthetics\", \"fantasy\"])\n",
        "        prompt = gr.Textbox(label=\"prompt\", lines=8, interactive=True)\n",
        "    essays = gr.Textbox(label=\"生成的作文\")\n",
        "    evaluate_res = gr.Textbox(label=\"评估结果\")\n",
        "    with gr.Row():\n",
        "        roll_button = gr.Button('Roll keywords')\n",
        "        prompt_button = gr.Button('生成prompt')\n",
        "        essay_button = gr.Button(\"生成作文\")\n",
        "        essay_refine = gr.Button(\"Refine 作文\")\n",
        "        evaluate_button = gr.Button('评估作文')\n",
        "    gr.Examples(gaokao_eamples,\n",
        "                title, label=\"作文题目示例\")\n",
        "    roll_button.click(fn=roll_keywords, inputs=openness[0], outputs=keywords)\n",
        "    prompt_button.click(fn=assemble_prompt, inputs=[title, openness[0], keywords, factors], outputs=[error_box, prompt])\n",
        "    essay_button.click(fn=generate_essay, inputs=prompt, outputs=essays)\n",
        "    essay_refine.click(fn=refine_essays, inputs=essays, outputs=essays)\n",
        "    evaluate_button.click(fn=evaluate_essays, inputs=essays, outputs=evaluate_res)\n",
        "\n",
        "demo.launch(debug=True, share=True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "5uu7GTki72V1"
      },
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "colab": {
      "include_colab_link": true,
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 2
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython2",
      "version": "2.7.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
